//================================= option 测试
pub mod t1_0 {
    use rust_test::common::*;
    use std::error::Error;

    pub fn tt() -> Result<(), Box<dyn std::error::Error>> {
        tt1()?;
        tt2()?;
        Ok(())
    }
    //----------------- option 接口
    #[mydbginfo]
    pub fn tt1() -> Result<(), Box<dyn std::error::Error>> {
        let some_number = Some(5);

        // Using map to transform the value inside the Option
        let doubled = some_number.map(|x| x * 2);

        println!("Original: {:?}, after map, Doubled: {:?}", some_number, doubled);

        let none_value: Option<i32> = None;

        // Using map on a None value
        let result = none_value.map(|x| x * 2);

        println!("None value: {:?}, Result after map: {:?}", none_value, result);

        // Option  实现了 map
        // pub fn map<U, F>(self, f: F) -> Option<U>
        // https://doc.rust-lang.org/std/option/enum.Option.html#method.map
        let maybe_some_string = Some(String::from("Hello, World!"));
        // `Option::map` takes self *by value*, consuming `maybe_some_string`
        let maybe_some_len = maybe_some_string.map(|s| s.len());
        blue_println!(r#"Some("hello, World!").map(len) => {:?}"#, maybe_some_len);
        assert_eq!(maybe_some_len, Some(13));

        let x: Option<&str> = None;
        assert_eq!(x.map(|s| s.len()), None);
        println!(r#"None.map(len) => {:?}"#, x);
        Ok(())
    }

    //--------------- option 接口, 模式匹配
    #[mydbginfo]
    pub fn tt2() -> Result<(), Box<dyn std::error::Error>> {
        let option: Option<i32> = Some(42);

        if let Some(x) = option {
            let x: i32 = x; // 显式声明 x 的类型
            blue_println!("renewed x is {}", x);
        }
        Ok(())
    }
}

//=========================== color 测试
pub mod t1_1 {
    use colored::control as clrdCtrl;
    use colored::Colorize;
    use rust_test::common::*;

    //---------------- color 测试
    #[mydbginfo]
    pub fn tt() -> Result<(), Box<dyn std::error::Error>> {
        let should_colored = clrdCtrl::SHOULD_COLORIZE.should_colorize();
        println!("{}", format!("should_colored: {should_colored}").blue());

        Ok(())
    }
}

//============================== deref 测试
pub mod t1_2 {

    use rust_test::common::*;
    use std::ops::Deref;

    pub fn tt() -> Result<(), Box<dyn std::error::Error>> {
        tt1()?;
        tt2()?;
        tt3()?;
        Ok(())
    }

    struct MyBox<T>(T);

    impl<T> MyBox<T> {
        fn new(x: T) -> MyBox<T> {
            MyBox(x)
        }
    }

    impl<T> Deref for MyBox<T> {
        type Target = T;

        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    fn display(s: &str) {
        println!("{}", s);
    }

    //------------------ deref 测试, String -> &str
    #[mydbginfo]
    pub fn tt1() -> Result<(), Box<dyn std::error::Error>> {
        let s = String::from("hello world");
        display(&s);
        Ok(())
    }

    //------------------ deref 测试, Box
    #[mydbginfo]
    pub fn tt2() -> Result<(), Box<dyn std::error::Error>> {
        let s = MyBox::new(String::from("hello world"));
        display(&s);
        Ok(())
    }

    //------------------ deref 测试, 连续 deref
    #[mydbginfo]
    pub fn tt3() -> Result<(), Box<dyn std::error::Error>> {
        let s = MyBox::new(String::from("hello, world"));
        let s1: &str = &s;
        // 调用了 ToString Trait 中的 to_string, 成员函数入参都是 &self, 会自动调用 deref
        let s2: String = s.to_string();
        Ok(())
    }

    //==========================
    fn display2(s: &mut String) {
        s.push_str("world");
        println!("{}", s);
    }
}

//================================= https://www.zhihu.com/question/651512341/answer/3453668271
// 泛型的类型标注, None 的类型推导
pub mod t1_3 {
    use std::default;

    use rust_test::common::*;
    //----- 远古rust允许 generic function 上的 default type parameter
    #[cfg(any())]
    pub fn foo<T = u64>(t: T) {
        println!("arguement {t}");
    }

    #[cfg(any())]
    pub fn tt1() {
        foo::<_>(22)
    } // foo::<i32> or foo::<u64> ?

    //===========================================
    pub fn foo2<T>(t: T)
    where
        T: std::fmt::Display,
    {
        println!("arguement {t}");
    }

    //----------- T = i32, 默认泛型参数
    #[mydbginfo]
    pub fn tt2() {
        let a = foo2::<_>(22);
        blue_println!("a= {a:?}");
    }

    //===========================================
    #[derive(Debug)]
    pub struct Builder<T = i32> {
        decorator: Option<T>,
    }
    impl<T> Builder<T> {
        pub fn new(decorator: Option<T>) -> Self {
            Self { decorator }
        }
    }

    //---------
    #[derive(Debug)]
    pub struct Builder2<U, T = i32> {
        u: U,
        decorator: Option<T>,
    }
    impl<U, T> Builder2<U, T> {
        pub fn new(u: U, decorator: Option<T>) -> Self {
            Self {
                u: u,
                decorator: decorator,
            }
        }
    }

    //------------------- 脱离泛型上下文
    #[mydbginfo]
    pub fn tt3() {
        // let x = Builder::new(None);

        // 1; 表示使用默认类型, 使用 default type parameter i32
        let x = <Builder>::new(None);
        dbg!(x);
        // 2; x 是 Builder 类型, 省略的类型参数使用 default type parameter, i32
        let x: Builder = Builder::new(None);
        dbg!(x);
        // 3. 当 generic parameter 存在一个及以上的非默认参数时，
        // turbofish 中省略的默认类型参数都会使用用户给定的默认类型，不使用 type infer 确定
        let x = Builder2::<()>::new((), None);
        dbg!(x);
    }
}

//================================= rust option 方法 与 Haskell Monad 对应
#[allow(unused_doc_comments)]
#[allow(unused_must_use)]
pub mod t1_4 {
    use rust_test::common::*;
    use std::error::Error;

    #[mydbginfo]
    pub fn tt3() {
        /** and_then 对应 Haskell 的 >>= 操作符; 返回 m b
         *
         * Rust: and_then<U, F>(self, f: F) -> Option<U> where F: FnOnce(T) -> Option<U>
         * Some(2).and_then(|x| Some(x * 2)); // Some(4)
         *
         * Monad m => m a -> (a -> m b) -> m b
         * Just 2 >>= (\x -> Just (x * 2))  -- Just 4
         */
        Some(2).and_then(|x| Some(x * 2)); // Some(4); 返回 m b

        /** map 对应 fmap; 返回 f b 即 m b
         *
         * Rust: map<U, F>(self, f: F) -> Option<U> where F: FnOnce(T) -> U
         * Some(2).map(|x| x * 2); // Some(4)
         *
         * Haskell: fmap 或 <$>（来自 Functor 类型类）
         * Functor f => (a -> b) -> f a -> f b
         * fmap (+1) (Just 3)   -- Just 4 ; 此处 fmap 是 Maybe 的 instance
         * (+1) <$> Just 3      -- Just 4
         */
        Some(2).map(|x| x * 2); // Some(4); 返回 f b 即 m b

        /** map_or 对应 Haskell 的 maybe 函数; 返回 b
         *
         * Rust: map_or<U, F>(self, default: U, f: F) -> U where F: FnOnce(T) -> U
         * Some("foo").map_or(42, |v| v.len()); // 3
         * None.map_or(42, |v: &str| v.len());   // 42
         *
         * Haskell: maybe（来自 Data.Maybe 模块）
         * maybe :: b->(a->b) -> Maybe a -> b
         * maybe 42 length (Just "foo")  -- 3
         * maybe 42 length Nothing       -- 42
         */
        Some("foo").map_or(42, |v| v.len()); // 3; 返回 b
        None.map_or(42, |v: &str| v.len()); // 42; 返回 b

        /** map_or_else, 对应 Haskell 的 maybe 函数; 返回 b
         *
         * Rust: map_or_else<U, D, F>(self, default: D, f: F) -> U where D: FnOnce() -> U, F: FnOnce(T) -> U
         * Some("foo").map_or_else(|| Err("null"), |x| Ok(x.len())); // 返回 Ok(3)
         * None.map_or_else(|| Err("null"), |x: &str| Ok(x.len())); // 返回 Err("null")
         *
         * Haskell: maybe, 来自 Data.Maybe 模块, 利用 Haskell 的惰性求值;
         * error :: GHC.Stack.Types.HasCallStack => [Char] -> a; error 可以匹配任意类型
         * 把 2nd参数应用到 3rd 参数, 如果3rd参数是 Just x, 否则返回 1st 参数.
         * maybe :: b->(a->b) -> Maybe a -> b
         * maybe (error "default") length (Just "foo")  -- 3
         * maybe (error "default") length Nothing       -- error "default"
         */
        Some("foo").map_or_else(|| Err("null"), |x| Ok(x.len())); // 返回 Ok(3); 返回 b
        None.map_or_else(|| Err("null"), |x: &str| Ok(x.len())); // 返回 Err("null")

        /** or_else 对应 Haskell 的 mplus 操作符; 返回 m a
         *
         * Rust: or_else<F>(self, f: F) -> Option<T> where F: FnOnce() -> Option<T>
         * Some(2).or_else(|| Some(3)); // Some(2)
         * None.or_else(|| Some(3));    // Some(3)
         *
         * Haskell: <|>（Alternative 运算符）或 mplus（MonadPlus 方法); 来自 Control.Monad 模块
         * MonadPlus m => m a -> m a -> m a
         * Nothing <|> Just 3   -- Just 3 (使用 Control.Applicative)
         * Nothing `mplus` Just 3 -- Just 3 (使用 Control.Monad)
         * Just 2 `mplus` Just 3 -- Just 2
         */
        Some(2).or_else(|| Some(3)); // Some(2)
        None.or_else(|| Some(3)); // Some(3)

        /** flatten, 对应 Haskell 的 join 函数; 返回 m a
         * Rust: flatten(self) -> Option<T> where T: Into<Option<T>>
         * Some(Some(2)).flatten(); // Some(2)
         * let x: Option<Option<u32>> = None;
         * x.flatten(); // None
         *
         * Haskell: join（来自 Monad 类型类）
         * join :: Monad m => m (m a) -> m a
         * join (Just (Just 3))  -- Just 3
         * join (Just Nothing)   -- Nothing
         */
        Some(Some(2)).flatten(); // Some(2)
        let x: Option<Option<u32>> = None;
        x.flatten(); // None

        /** transpose, 对应 Haskell 的 sequence 函数; 返回 m (f a)
         * Rust: transpose(self) -> Result<Option<T>, E>（用于 Option<Result<T, E>>）
         * Some(Ok::<i32, ()>(2)).transpose(); // Some(2)
         * Some(Err::<i32, &str>("error")).transpose(); // Err("error")
         * let x: Option<Result<u32, ()>> = None;
         * x.transpose(); // None
         *
         * Haskell: sequence 或 sequenceA（来自 Traversable 类型类）
         * sequence :: (Traversable t, Applicative f) => t (f a) -> f (t a)
         * sequence (Just (Right 3))   -- Right (Just 3)
         * sequence (Just (Left "err")) -- Left "err"
         */
        Some(Ok::<i32, ()>(2)).transpose(); // Some(2)
        Some(Err::<i32, &str>("error")).transpose(); // Err("error")
        let x: Option<Result<u32, ()>> = None;
        x.transpose(); // None

        /** unwrap, 对应 Haskell 的 fromJust 函数; 返回 a
         * Rust: unwrap(self) -> T（None 时 panic）
         * let x: Option<u32> = None;
         * x.unwrap(); // panic: called `Option::unwrap()` on a `None` value
         *
         * Haskell: fromJust（来自 Data.Maybe 模块，不安全）
         * fromJust :: Maybe a -> a
         * fromJust (Just 3)  -- 3
         * fromJust Nothing   -- 抛出异常
         */
        Some(2).unwrap(); // 2
        let x: Option<u32> = None;
        //x.unwrap(); // panic: called `Option::unwrap()` on a `None` value

        /** unwrap_or, 对应 Haskell 的 fromMaybe 函数; 返回 a
         * Rust: unwrap_or(self, default: T) -> T
         * Some(2).unwrap_or(42); // 2
         * None.unwrap_or(42); // 42
         *
         * Haskell: fromMaybe（来自 Data.Maybe）
         * fromMaybe :: a -> Maybe a -> a
         * fromMaybe 0 (Just 3)  -- 3
         * fromMaybe 0 Nothing    -- 0
         */
        Some(2).unwrap_or(42); // 2
        None.unwrap_or(42); // 42

        /** is_some / is_none, 对应 Haskell 的 isJust / isNothing 函数; 返回 bool
         * Rust: is_some(self) -> bool, is_none(self) -> bool ;检查 Some 或 None
         * Some(2).is_some(); // true
         * None::<Option<i32>>.is_some(); // false
         *
         * Haskell: isJust / isNothing（来自 Data.Maybe）
         * isJust :: Maybe a -> Bool
         * isJust (Just 3)  -- True
         * isJust Nothing   -- False
         */
        Some(2).is_some(); // true
        None::<Option<i32>>.is_some(); // false
    }
}
